package dao

import (
	"blog/model"
	"blog/model/constants"
	"gitea.com/lunny/log"
	"sort"
	"time"
)

var ArticleDao = &articleDao{}

type articleDao struct {
}

// 新增文章
func (dao articleDao) ArticleAdd(article *model.Article) bool {
	sess := Db.NewSession()
	article.CreateTime = time.Now()
	article.DataState = constants.DataSate_ENABLE
	if _, err := Db.Insert(article); err != nil {
		_ = sess.Rollback()
		log.Infof("新增文章失败", err)
		return false
	}
	_ = sess.Commit()
	return true
}

// 查询文章
func (dao articleDao) ArticleGet(id interface{}) (*model.Article, bool) {
	mod := &model.Article{}
	switch val := id.(type) {
	case int:
		has, _ := Db.ID(val).Get(mod)
		return mod, has
	default:
		return mod, false
	}
}

// 更新文章内容
func (dao articleDao) ArticleUpdate(id int, article *model.Article) error {
	sess := Db.NewSession()
	if _, err := Db.ID(id).Update(article); err != nil {
		return sess.Rollback()
	}
	return sess.Commit()
}

// 更新文章状态
func (dao articleDao) ArticleStateUpdate(id interface{}, state interface{}) error {
	sess := Db.NewSession()
	if _, err := Db.Table(new(model.Article)).ID(id).Update(map[string]interface{}{"DataState": state}); err != nil {
		return sess.Rollback()
	}
	return sess.Commit()
}

// 分页查询文章
func (dao articleDao) ArticlePage(pageNumber int, pageSize int, article *model.Article) ([]*model.Article, int64, error) {
	mods := make([]*model.Article, 0, pageSize)
	sess := Db.NewSession()
	defer sess.Close()
	data1 := time.Now()
	column := "atc_id, user_id, user_name, topic_id, title, cover, atc_state, create_time, drop_time, data_state, summary, sched, sched_time, dir"
	total, err := sess.Select(column).Desc("atc_id").Limit(pageSize, (pageNumber-1)*pageSize).FindAndCount(&mods, article)
	data2 := time.Now()
	log.Info("查询耗时 = {}", data2.Nanosecond()-data1.Nanosecond())
	for _, dto := range mods {
		dto.Content = ""
		dto.Markdown = ""
		dto.Dir = ""
	}

	return mods, total, err
}

func (dao *articleDao) CountArticle(condition *model.Article) (int64, error) {
	return Db.Count(condition)
}

func (dao *articleDao) Archive() interface{} {
	results, _ := Db.QueryInterface(
		"   SELECT   article.atc_id atcId, article.title, article.create_time createTime,  CONCAT_WS(\"-\",YEAR(create_time),MONTH(create_time)) date\n" +
			"    FROM article\n" +
			"    where create_time is not null and data_state = 0 and atc_state = 1\n" +
			"    ORDER BY create_time DESC")
	resultMap := make(map[interface{}][]interface{})
	for _, value := range results {
		resultMap[value["date"]] = append(resultMap[value["date"]], value)
	}

	var result []ArchiveDTO

	for k, v := range resultMap {
		acv := ArchiveDTO{k, len(v), v}
		result = append(result, acv)
	}

	sort.SliceStable(result, func(i, j int) bool {
		d1, _ := time.Parse("2006-1", result[i].Date.(string))
		d2, _ := time.Parse("2006-1", result[j].Date.(string))
		return d1.After(d2)
	})

	return result
}

type ArchiveDTO struct {
	Date     interface{}   `json:"date"`
	Num      int           `json:"num"`
	Articles []interface{} `json:"articles"`
}
